<template>
  <a-card
    class="common-content-wrap"
    :bordered="false"
    :style="{ minHeight: `${layoutContentHeight - pageHeaderHeight - layoutFooterHeight}px` }"
  >
    <div style="display: flex">
      <a-col class="gutter-row" :xs="{ span: 24 }" :sm="{ span: 4 }">
        <resizable-grid>
          <a-tree
            class="tree--custom has-menu"
            :defaultExpandAll="true"
            :showIcon="false"
            :treeData="groupTree"
            :expandedKeys.sync="expandedKeys"
            :selectedKeys="selectedKeys"
            @select="onSelectTreeNode"
          >
            <template slot="title" slot-scope="scopeProps">
              <div class="tree--custom-node">
                <div class="tree--custom-node-text" :title="scopeProps.name">
                  <!--<ellipsis length="100%" tooltip>-->
                  <!--{{scopeProps.name}}-->
                  <!--</ellipsis>-->
                  {{ scopeProps.name }}
                </div>
                <div class="tree--custom-node-menu" v-action:add|edit|delete>
                  <a-dropdown :trigger="['hover']">
                    <a class="ant-dropdown-link" href="javascript:;">
                      <a-icon type="more" />
                    </a>
                    <a-menu slot="overlay" @click="({ key }) => onClickTreeDropdown(key, scopeProps)">
                      <a-menu-item key="add" v-action:add>
                        <a-icon type="plus" />
                        创建子用户组
                      </a-menu-item>
                      <a-menu-item key="edit" :disabled="scopeProps.name === '超级管理组'" v-action:edit>
                        <a-icon type="edit" />
                        编辑用户组
                      </a-menu-item>
                      <a-menu-item key="delete" :disabled="scopeProps.name === '超级管理组'" v-action:delete>
                        <a-icon type="delete" />
                        删除用户组
                      </a-menu-item>
                      <a-menu-divider v-if="!scopeProps.isRoot" v-action:edit />
                      <a-menu-item
                        v-if="!scopeProps.isRoot"
                        key="up"
                        :disabled="scopeProps.name === '超级管理组' || scopeProps.serialNum === 1"
                        v-action:edit
                      >
                        <a-icon type="sort-descending" />
                        {{ $t('common.moveUp') }}
                      </a-menu-item>
                      <a-menu-item
                        v-if="!scopeProps.isRoot"
                        key="down"
                        :disabled="scopeProps.name === '超级管理组' || scopeProps.serialNum === scopeProps.levelLength"
                        v-action:edit
                      >
                        <a-icon type="sort-ascending" />
                        {{ $t('common.moveDown') }}
                      </a-menu-item>
                    </a-menu>
                  </a-dropdown>
                </div>
              </div>
            </template>
          </a-tree>
        </resizable-grid>
      </a-col>
      <a-col
        class="gutter-row"
        style="padding-left: 20px; border-left: 1px solid #e8e8e8"
        :xs="{ span: 24 }"
        :sm="{ span: 19 }"
        :style="{ minHeight: `${layoutContentHeight - pageHeaderHeight}px` }"
      >
        <div class="common-content-wrap">
          <div class="content-item" v-if="selectedGroup.name !== '超级管理组'">
            <div class="title">{{ $t('common.member') }}</div>
            <div class="content">
              <template v-for="x in members">
                <a-tag closable :key="x.id" @close="deleteMember(x.id)">
                  <a-icon type="folder" v-if="x.isOrg" /><span>{{ x.name }}</span>
                </a-tag>
              </template>
              <a href="javascript:;" @click="openMemberSelectModal">
                <a-icon type="plus" v-action:add />
              </a>
            </div>
          </div>
          <div class="content-item" v-if="selectedGroup.name !== '超级管理组'">
            <div class="title">{{ $t('authenticationCenter.role.role') }}</div>
            <div class="content">
              <template v-for="r in roles">
                <a-tag closable :key="r.id" @close="deleteRole(r.id)" :class="{ danger: r.isBuiltIn }">{{
                  r.name
                }}</a-tag>
              </template>
              <a href="javascript:;" @click="openRoleSelectModal">
                <a-icon type="plus" v-action:add />
              </a>
            </div>
          </div>
          <div class="content-item" v-else>
            <div class="title">{{ $t('authenticationCenter.role.role') }}</div>
            <div class="content">
              <div class="admin-all">{{ $t('authenticationCenter.userGroup.allRoles') }}</div>
            </div>
          </div>
        </div>
      </a-col>
    </div>
    <group-form ref="groupForm" :appId="appId" :groupTree="groupTree" @ok="getUserGroupTree" />
    <select-modal
      ref="selectModalMember"
      :title="$t('authenticationCenter.userGroup.selectMember')"
      :subTitle="$t('authenticationCenter.userGroup.orgnization')"
      :tree-data="managerOrgTree"
      :defaultSelectedTreeKeys="defaultSelectedMemberTreeKeys"
      :inputNumber="false"
      :treeCheckable="true"
      :treeCheckStrictly="true"
      :select-tree-node="loadMemberUserData"
      @sure="handleAddMember"
    ></select-modal>
    <select-role ref="selectRoleModal" :appId="appId" :group-id="selectedGroup.id" :roles="roles" @ok="getGroupRoles" />
  </a-card>
</template>

<script>
import { breadFirstTree, setArrayToTree } from '@/utils/util'
import { layoutMixin } from '@/utils/mixin'
import { ResizableGrid } from '@/components'
import SelectModal from '@/components/SelectModal/SelectModal'
import GroupForm from '@/views/authenticationCenter/userGroup/GroupForm.vue'
import SelectRole from '@/views/authenticationCenter/userGroup/SelectRole.vue'
import {
  getUserGroupTree,
  deleteGroupTree,
  upGroupTree,
  downGroupTree,
  getManagers,
  getAppOrg,
  getAppOrgMember,
  addManager,
  deleteManager,
  getMembers,
  addMember,
  deleteMember,
  getRoles,
  deleteRole
} from '@/api/authenticationCenter/config/userGroup'

export default {
  name: 'UserGroup',

  components: {
    ResizableGrid,
    GroupForm,
    SelectModal,
    SelectRole
  },
  mixins: [layoutMixin],
  data () {
    return {
      selectedKeys: [],
      expandedKeys: [],
      selectedGroup: {
        id: 1
      },
      groupTree: [],

      managers: [],
      managerOrgTree: [],
      defaultSelectedMemberTreeKeys: [],
      members: [],
      membersSet: new Set(),
      roles: [],
      appId: 0
    }
  },
  created () {
    this.getUserGroupTree()
  },
  methods: {
    getUserGroupTree (updateExpandedKeys) {
      return getUserGroupTree({
        appId: this.appId
      }).then(res => {
        // 进入breadFirstTree之后已经无法处理最外层node了，只能在这里处理
        const data = res.data.map((ele, index) => {
          ele.index = index
          ele.levelLength = res.data.length
          return ele
        })
        if (!updateExpandedKeys) this.expandedKeys = []
        breadFirstTree(
          data,
          node => {
            node.scopedSlots = {
              title: 'title'
            }
            node.title = node.name
            node.key = node.id
            node.value = node.id
            if (node.children && node.children.length > 0) {
              node.children.forEach(item => {
                item.levelLength = node.children.length
              })
            }
            if (!updateExpandedKeys) this.expandedKeys.push(node.id)
            return true
          },
          // eslint-disable-next-line
          'children'
        )
        let selectedGroup = data[0]
        if (this.selectedKeys.length > 0) {
          breadFirstTree(
            data,
            node => {
              if (node.id === this.selectedKeys[0]) {
                selectedGroup = node
                return false
              }
              return true
            },
            // eslint-disable-next-line
            'children'
          )
        }
        this.groupTree = data
        selectedGroup && this.onSelectTreeNode([selectedGroup.key], selectedGroup)
      })
    },
    onSelectTreeNode (keys, data) {
      // 反选当前节点不予理会
      if (keys.length === 0) return
      this.selectedGroup = data.node ? data.node.dataRef : data
      if (this.selectedKeys[0] !== keys[0]) {
        this.selectedKeys = keys
        if (this.selectedGroup.name !== '超级管理组') {
          this.getGroupMembers()
          this.getGroupRoles()
        }
      }
    },
    onClickTreeDropdown (key, node) {
      if (key === 'add') {
        this.$refs.groupForm.add(node)
      } else if (key === 'edit') {
        this.$refs.groupForm.edit(node)
      } else if (key === 'delete') {
        if (node.children && node.children.length > 0) {
          this.$warning({
            title: this.$t('common.info'),
            content: '父用户组还有子用户组无法删除，请先移除'
          })
        } else {
          this.$confirm({
            title: this.$t('common.info'),
            content: this.$t('common.delWarning', {
              name: this.$t('authenticationCenter.userGroup.userGroup').toLowerCase()
            }),
            okType: 'danger',
            onOk: () => {
              deleteGroupTree(node.id).then(res => {
                if (node.id === this.selectedKeys[0]) {
                  this.selectedKeys = [node.parentId]
                }
                this.getUserGroupTree(1)
                this.$message.success(res.message)
              })
            }
          })
        }
      } else if (key === 'up') {
        upGroupTree({
          id: node.id,
          appId: this.appId
        }).then(res => {
          this.getUserGroupTree(1)
          this.$message.success(res.message)
        })
      } else if (key === 'down') {
        downGroupTree({
          id: node.id,
          appId: this.appId
        }).then(res => {
          this.getUserGroupTree(1)
          this.$message.success(res.message)
        })
      }
    },
    /**
     * 根据数组对象的某个字段去重
     * item.name  是[{name:1}] 根据每条数据的name值来去重
     * */
    unique (arr, val) {
      const res = new Map()
      return arr.filter(item => !res.has(item[val]) && res.set(item[val], 1))
    },
    // 成员相关
    getGroupMembers () {
      getMembers({
        groupId: this.selectedGroup.id
      }).then(res => {
        this.members = res.data
        this.membersChange()
      })
    },
    openMemberSelectModal () {
      this.$refs.selectModalMember.open()
      getAppOrg().then(res => {
        const list = res.data
        console.log(list)
        const tree = setArrayToTree({
          data: list,
          pid: 'parentId'
        })
        breadFirstTree(
          tree,
          node => {
            // 已选择的群组不可重复选择
            if (this.members.find(d => d.unionId === node.id && d.isOrg)) {
              node.disabled = true
            }
            node.scopedSlots = {
              title: 'title'
            }
            node.title = node.name
            node.key = node.id
            return true
          },
          // eslint-disable-next-line
          'children'
        )
        this.managerOrgTree = tree
        this.defaultSelectedMemberTreeKeys = this.managerOrgTree.length > 0 ? [this.managerOrgTree[0].key] : []
      })
    },
    loadMemberUserData (node, resolve) {
      getAppOrgMember({
        pageNo: 1,
        pageSize: 9999,
        id: node.id,
        status: 1
      }).then(res => {
        const data = this.unique(res.data.data, 'id')
        data.forEach(item => {
          item.label = item.name
          item.value = item.id
          this.members.forEach(m => {
            if (!m.isOrg && m.unionId === item.id) {
              item.disabled = true
            }
          })
          if (this.membersSet.has(item.id)) {
            item.disabled = true
          }
        })
        resolve(data)
      })
    },
    membersChange () {
      this.membersSet.clear()
      this.members.forEach(d => {
        if (d.isOrg) {
          getAppOrgMember({
            pageNo: 1,
            pageSize: 9999,
            id: d.unionId,
            status: 1
          }).then(({ data }) => {
            data.data.forEach(item => {
              this.membersSet.add(item.id)
            })
          })
        }
      })
    },
    handleAddMember (data) {
      this.$refs.selectModalMember.setSureLoading(true)
      const newData = []
      data.forEach(item => {
        newData.push({
          userGroupId: this.selectedGroup.id,
          unionId: item.value,
          isOrg: item.type === 'tree' ? 1 : 0
        })
      })
      addMember(newData)
        .then(() => {
          this.$refs.selectModalMember.setSureLoading(false)
          this.$refs.selectModalMember.close()
          this.getGroupMembers()
        })
        .catch(() => {
          this.$refs.selectModalMember.setSureLoading(false)
          this.$refs.selectModalMember.close()
          this.getGroupMembers()
        })
    },
    deleteMember (id) {
      deleteMember({
        id
      }).then(() => {
        this.getGroupMembers()
      })
    },

    // 角色相关
    getGroupRoles () {
      getRoles({
        groupId: this.selectedGroup.id
      }).then(res => {
        this.roles = res.data
      })
    },
    openRoleSelectModal () {
      this.$refs.selectRoleModal.open()
    },
    deleteRole (id) {
      deleteRole({
        id
      }).then(() => {
        this.getGroupRoles()
      })
    }
  }
}
</script>

<style lang="less" scoped>
/deep/ .ant-card-body {
  padding: 0;
}
.content-item {
  padding: 10px 0 20px;
  /*position: relative;*/
  border-bottom: 1px solid #e4e6e9;
  /*min-height: 80px;*/
  /*vertical-align: middle;*/
  display: flex;
  align-items: center;
  .title {
    margin-top: 10px;
    width: 110px;
  }

  .content {
    flex: 1;
    .ant-tag {
      margin-top: 10px;
      &.danger {
        color: red;
      }
    }
    > a {
      display: inline-block;
      margin-top: 10px;
    }
  }
  .content-sub-title {
    margin-top: 15px;
    font-weight: bold;
  }
}

.manager-list-item {
  padding: 0 0 10px;
  border-bottom: 1px dashed #e4e6e9;
  a {
    display: inline-block;
    margin-top: 10px;
  }
}

.admin-all {
  font-weight: bold;
  margin-top: 10px;
}
</style>
